<?php
class ps_MetaBase_Driver_Filesystem extends ps_MetaBase_Driver implements ps_MetaBase_iDriver {
  protected $config = array(
	'name'=>'Filesystem',
	'namespace'=>'SweetApp',
	/* 'path'=>'./cache', */
	'lifetime'=>60, // Expire files older than # seconds, exclude or set to 0 for infinite
	'purgeProbability'=>1,
	'purgeDivisor'=>100
  );
  public function __construct( $config ) {
    $this->applyConfig( $config );
    if ( !isset( $this->config['path'] ) ) { $this->config['path'] = PS_METABASE_PATH . '/cache'; }

    $this->initCache();

    if ( $this->config['lifetime'] > 0 ) {
      $this->pergeCache();
    }
  }
  public function store( $key, $data ) {
    $key = $this->getNamespace( '-' ) . $key;
    $fh = fopen( $this->getFilePath( $key ), 'w+' );
    fwrite($fh, serialize( $data ) );
    fclose( $fh );
  }

  public function fetch( $key ) {
    $key = $this->getNamespace( '-' ) . $key;
    if ( file_exists( $this->getFilePath( $key ) ) ) {
	return unserialize( file_get_contents( $this->getFilePath( $key ), 'r' )) ;
    } else { return false;}
  }
  public function pergeCache() {
    //TODO Delete all .pstore cache files in cache directory
    if ( $this->probability( $this->config['purgeProbability'], $this->config['purgeDivisor'] ) ) {
      $this->purgeOlder(  $this->getPath(), $this->config['lifetime'] );
    }
  }

  /** 
   * Delete Cache files that are more than $seconds old
   */
  protected function purgeOlder( $dir, $seconds=86400 ) {
    if( !$dirhandle = @opendir( $dir ) ) {
      return;
    }

    while( false !== ( $filename = readdir($dirhandle) ) ) {
      if( substr($filename, -7 ) == '.pstore' ) {
        $filename =  $dir . '/' . $filename;
        if( @filemtime($filename) < ( time() - $seconds ) ) {
		@unlink($filename);
	}
      }
    }
  }

  protected function initCache() {
    if ( !file_exists( $this->getPath() ) ) {
	mkdir( $this->getPath(), 0700 );

	$this->plantClue();
	if ( !file_exists( $this->getPath() ) ) {	
	   echo 'Unable to create ' . $this->getPath() . 'directory .  Check permissions';
	   exit;
  	}
    }
  }

  protected function plantClue() {
    $fh = fopen( $this->getPath() . '/README', 'w+');
    fwrite( $fh, 'This directory was created by the ps_MetaBase PHP library and is used for persistent caching to disk.');
    fclose( $fh );
  }

  /** 
   * Extract namespace from driver config
   * Namespaces are optional for drivers and good practice for shared persistent stores
   */
  protected function getNamespace( $append=NULL ) {
	if ( $this->config['namespace'] ) {
	  $namespace = $this->config['namespace'];
	}
	if ( $append ) { 
	  return $namespace . $append;
	}
	return $namespace;
  }
   
  /** 
   * Get the path to the filesystem store
   */
  protected function getPath() {
	return $this->config['path'];
  }

  /**
   * returns hashed filename with .pstore extension
   */
  protected function getFilename( $key ) {
	return  sha1( $key ) . '.pstore';
  }
  protected function getFilePath( $key ) {
	$filename = $this->getFilename( $key );
	$presplit = substr( $filename, 0, 2);
	// Big Filesystem
	// return $this->getPath() . '/' . $presplit  . '/' . $filename;
	return $this->getPath() . '/' . $filename;
  }
}
?>
